import { defineStore } from 'pinia';

import config from '@/config';
import { LocalStorageService } from '@/utils/storage';

type State = {
  visitedViews: TypeObject,
  cachedViews: string[]
}

const cName = 'name';
const max = config.multipleNav.max; // 最多可以缓存多少组件实例。
const clientId = config.multipleNav.clientId;

export const useKeepAliveStore = defineStore('_keepAlive', {
  state: (): State => ({
    visitedViews: LocalStorageService.get('_visited_views') || {}, // 多导航标签
    cachedViews: [],
  }),
  actions: {
    addTagOnly(route: TypeObject) {
      const fixedViews = config.multipleNav.fixedRoutes.map((i) => i.fullPath);
      const visitedViewsTemp = this.visitedViews[clientId] || [];
      const index = visitedViewsTemp.findIndex((vRoute: TypeObject) => vRoute[cName] === route[cName]);
      const routeInfo = {
        fullPath: route.fullPath,
        hash: route.hash,
        meta: route.meta,
        name: route.name,
        params: route.params,
        path: route.path,
        query: route.query,
      };
      if (index > -1) {
        visitedViewsTemp[index] = routeInfo;
        this.visitedViews[clientId] = visitedViewsTemp;
        LocalStorageService.set('_visited_views', this.visitedViews);
        return;
      }
      if (!fixedViews.includes(routeInfo.path)) {
        visitedViewsTemp.push(routeInfo);
      }
      this.visitedViews[clientId] = visitedViewsTemp;
      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    addCacheOnly(route: TypeObject) {
      if (!route[cName]) {
        return;
      }

      const fixedViewsCached = config.multipleNav.fixedViews;
      const cachedKey = route[cName];
      if (this.cachedViews.includes(cachedKey)) { // 已缓存先删除缓存的key
        const index = this.cachedViews.indexOf(cachedKey);
        if (index > -1) {
          this.cachedViews.splice(index, 1);
        }
      }
      if (!(fixedViewsCached as any[]).includes(cachedKey)) {
        this.cachedViews.push(cachedKey);
      }
      if (this.cachedViews.length > max) {
        // 超过缓存限制，删除最近不常操作的缓存
        this.cachedViews = this.cachedViews.slice(-max);
      }
    },

    addTagAndCache(route: TypeObject) {
      this.addTagOnly(route);
      this.addCacheOnly(route);
    },

    deleteTagOnly(route: TypeObject) {
      const visitedViewsTemp = this.visitedViews[clientId] || [];
      const index = visitedViewsTemp.findIndex((nav: TypeObject) => nav.fullPath === route.fullPath);
      if (index > -1) {
        visitedViewsTemp.splice(index, 1);
      }

      this.visitedViews[clientId] = visitedViewsTemp;
      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    deleteCacheOnly(route: TypeObject) {
      const cachedKey = route[cName];
      const index = this.cachedViews.indexOf(cachedKey);
      if (index > -1) {
        this.cachedViews.splice(index, 1);
      }
    },

    deleteTagAndCache(route: TypeObject) {
      this.deleteTagOnly(route);
      this.deleteCacheOnly(route);
    },

    setVisitedViews(visitedViews: TypeObject) {
      this.visitedViews[clientId] = visitedViews;
      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    deleteOtherTagAndCache(route: TypeObject) {
      const visitedViewsTemp = this.visitedViews[clientId] || [];
      const curIndex = visitedViewsTemp.findIndex((nav: TypeObject) => nav.fullPath === route.fullPath);
      const visitedView = visitedViewsTemp[curIndex];
      const key = route[cName];
      this.visitedViews[clientId] = visitedView ? [visitedView] : [];
      this.cachedViews = key ? [key] : [];

      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    deleteLeftTagAndCache(route: TypeObject) {
      const visitedViewsTemp = this.visitedViews[clientId] || [];
      const curIndex = visitedViewsTemp.findIndex((nav: TypeObject) => nav.fullPath === route.fullPath);
      const visitedViewsRight = visitedViewsTemp.slice(curIndex);
      this.visitedViews[clientId] = visitedViewsRight;

      const rightViewsKeys = visitedViewsRight.map((nav: TypeObject) => nav.name || '');
      this.cachedViews = this.cachedViews.filter((key: string) => rightViewsKeys.includes(key));

      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    deleteRightTagAndCache(route: TypeObject) {
      const visitedViewsTemp = this.visitedViews[clientId] || [];
      const curIndex = visitedViewsTemp.findIndex((nav: TypeObject) => nav.fullPath === route.fullPath);
      const visitedViewsLeft = visitedViewsTemp.slice(0, curIndex + 1);
      this.visitedViews[clientId] = visitedViewsLeft;

      const leftViewsKeys = visitedViewsLeft.map((nav: TypeObject) => nav.name || '');
      this.cachedViews = this.cachedViews.filter((key: string) => leftViewsKeys.includes(key));

      LocalStorageService.set('_visited_views', this.visitedViews);
    },

    deleteAllTagAndCache() {
      this.visitedViews[clientId] = [];
      this.cachedViews = [];
      LocalStorageService.set('_visited_views', this.visitedViews);
    },
  },
});
